using System;
using System.Reflection;
using UnityEngine;
using UnityEngine.EventSystems;

namespace EntityKit.Runtime
{
    public partial class BindService
    {
        private static void UIPointerDownBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIPointerDownBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"按下绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), Type.EmptyTypes))
            {
                Debug.LogError($"按下方法签名错误：{method.Name} 必须是无参void方法");
                return;
            }
            
            var eventTrigger = gameObject.GetComponent<EventTrigger>() ?? gameObject.AddComponent<EventTrigger>();
            RecordUIComponent(component, eventTrigger); 
            
            // 检查是否已存在相同类型的事件
            foreach (var entry in eventTrigger.triggers)
            {
                if (entry.eventID == EventTriggerType.PointerDown)
                {
                    Debug.LogWarning($"GameObject '{gameObject.name}' 上已存在PointerDown事件，将添加重复监听器");
                    break;
                }
            }
            
            var newEntry = new EventTrigger.Entry
            {
                eventID = EventTriggerType.PointerDown
            };
            newEntry.callback.AddListener((data) => {
                method.Invoke(component, null);
            });

            eventTrigger.triggers.Add(newEntry);
        }

        private static void UIPointerUpBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIPointerUpBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"抬起绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), Type.EmptyTypes))
            {
                Debug.LogError($"抬起方法签名错误：{method.Name} 必须是无参void方法");
                return;
            }
            
            var eventTrigger = gameObject.GetComponent<EventTrigger>() ?? gameObject.AddComponent<EventTrigger>();
            RecordUIComponent(component, eventTrigger); 
            
            // 检查是否已存在相同类型的事件
            foreach (var entry in eventTrigger.triggers)
            {
                if (entry.eventID == EventTriggerType.PointerUp)
                {
                    Debug.LogWarning($"GameObject '{gameObject.name}' 上已存在PointerUp事件，将添加重复监听器");
                    break;
                }
            }
            
            var newEntry = new EventTrigger.Entry
            {
                eventID = EventTriggerType.PointerUp
            };
            
            newEntry.callback.AddListener((data) => {
                method.Invoke(component, null);
            });

            eventTrigger.triggers.Add(newEntry);
        }

        private static void UIPointerEnterBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIPointerEnterBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"PointerEnter绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), Type.EmptyTypes))
            {
                Debug.LogError($"PointerEnter方法签名错误：{method.Name} 必须是无参void方法");
                return;
            }
            
            var eventTrigger = gameObject.GetComponent<EventTrigger>() ?? gameObject.AddComponent<EventTrigger>();
            RecordUIComponent(component, eventTrigger); 
            
            // 检查是否已存在相同类型的事件
            foreach (var entry in eventTrigger.triggers)
            {
                if (entry.eventID == EventTriggerType.PointerEnter)
                {
                    Debug.LogWarning($"GameObject '{gameObject.name}' 上已存在PointerEnter事件，将添加重复监听器");
                    break;
                }
            }
            
            var newEntry = new EventTrigger.Entry
            {
                eventID = EventTriggerType.PointerEnter
            };
            
            newEntry.callback.AddListener((data) => {
                method.Invoke(component, null);
            });

            eventTrigger.triggers.Add(newEntry);
        }

        private static void UIPointerExitBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIPointerExitBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"PointerExit绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), Type.EmptyTypes))
            {
                Debug.LogError($"PointerExit方法签名错误：{method.Name} 必须是无参void方法");
                return;
            }
            
            var eventTrigger = gameObject.GetComponent<EventTrigger>() ?? gameObject.AddComponent<EventTrigger>();
            RecordUIComponent(component, eventTrigger); 
            
            // 检查是否已存在相同类型的事件
            foreach (var entry in eventTrigger.triggers)
            {
                if (entry.eventID == EventTriggerType.PointerExit)
                {
                    Debug.LogWarning($"GameObject '{gameObject.name}' 上已存在PointerExit事件，将添加重复监听器");
                    break;
                }
            }
            
            var newEntry = new EventTrigger.Entry
            {
                eventID = EventTriggerType.PointerExit
            };
            
            newEntry.callback.AddListener((data) => {
                method.Invoke(component, null);
            });

            eventTrigger.triggers.Add(newEntry);
        }

        private static void UIDragBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIDragBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"拖拽绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), new[] { typeof(PointerEventData) }))
            {
                Debug.LogError($"拖拽方法签名错误：{method.Name} 必须是 void Method(PointerEventData)");
                return;
            }
            
            var eventTrigger = gameObject.GetComponent<EventTrigger>() ?? gameObject.AddComponent<EventTrigger>();
            RecordUIComponent(component, eventTrigger); 
            
            // 检查是否已存在相同类型的事件
            foreach (var entry in eventTrigger.triggers)
            {
                if (entry.eventID == EventTriggerType.Drag)
                {
                    Debug.LogWarning($"GameObject '{gameObject.name}' 上已存在Drag事件，将添加重复监听器");
                    break;
                }
            }
            
            var newEntry = new EventTrigger.Entry
            {
                eventID = EventTriggerType.Drag
            };
            
            newEntry.callback.AddListener((data) => {
                method.Invoke(component, new object[] { data });
            });

            eventTrigger.triggers.Add(newEntry);
        }

        private static void UIBeginDragBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIBeginDragBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"开始拖拽绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), new[] { typeof(PointerEventData) }))
            {
                Debug.LogError($"开始拖拽方法签名错误：{method.Name} 必须是 void Method(PointerEventData)");
                return;
            }
            
            var eventTrigger = gameObject.GetComponent<EventTrigger>() ?? gameObject.AddComponent<EventTrigger>();
            RecordUIComponent(component, eventTrigger); 
            
            // 检查是否已存在相同类型的事件
            foreach (var entry in eventTrigger.triggers)
            {
                if (entry.eventID == EventTriggerType.BeginDrag)
                {
                    Debug.LogWarning($"GameObject '{gameObject.name}' 上已存在BeginDrag事件，将添加重复监听器");
                    break;
                }
            }
            
            var newEntry = new EventTrigger.Entry
            {
                eventID = EventTriggerType.BeginDrag
            };
            
            newEntry.callback.AddListener((data) => {
                method.Invoke(component, new object[] { data });
            });

            eventTrigger.triggers.Add(newEntry);
        }

        private static void UIEndDragBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIEndDragBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"结束拖拽绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), new[] { typeof(PointerEventData) }))
            {
                Debug.LogError($"结束拖拽方法签名错误：{method.Name} 必须是 void Method(PointerEventData)");
                return;
            }
            
            var eventTrigger = gameObject.GetComponent<EventTrigger>() ?? gameObject.AddComponent<EventTrigger>();
            RecordUIComponent(component, eventTrigger); 
            
            // 检查是否已存在相同类型的事件
            foreach (var entry in eventTrigger.triggers)
            {
                if (entry.eventID == EventTriggerType.EndDrag)
                {
                    Debug.LogWarning($"GameObject '{gameObject.name}' 上已存在EndDrag事件，将添加重复监听器");
                    break;
                }
            }
            
            var newEntry = new EventTrigger.Entry
            {
                eventID = EventTriggerType.EndDrag
            };
            
            newEntry.callback.AddListener((data) => {
                method.Invoke(component, new object[] { data });
            });

            eventTrigger.triggers.Add(newEntry);
        }

        private static void UIScrollBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIScrollBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"滚动绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), new[] { typeof(PointerEventData) }))
            {
                Debug.LogError($"滚动方法签名错误：{method.Name} 必须是 void Method(PointerEventData)");
                return;
            }
            
            var eventTrigger = gameObject.GetComponent<EventTrigger>() ?? gameObject.AddComponent<EventTrigger>();
            RecordUIComponent(component, eventTrigger); 
            
            // 检查是否已存在相同类型的事件
            foreach (var entry in eventTrigger.triggers)
            {
                if (entry.eventID == EventTriggerType.Scroll)
                {
                    Debug.LogWarning($"GameObject '{gameObject.name}' 上已存在Scroll事件，将添加重复监听器");
                    break;
                }
            }
            
            var newEntry = new EventTrigger.Entry
            {
                eventID = EventTriggerType.Scroll
            };
            
            newEntry.callback.AddListener((data) => {
                method.Invoke(component, new object[] { data });
            });

            eventTrigger.triggers.Add(newEntry);
        }

        private static void UISelectBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UISelectBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"选中绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), Type.EmptyTypes))
            {
                Debug.LogError($"选中方法签名错误：{method.Name} 必须是无参void方法");
                return;
            }
            
            var eventTrigger = gameObject.GetComponent<EventTrigger>() ?? gameObject.AddComponent<EventTrigger>();
            RecordUIComponent(component, eventTrigger); 
            
            // 检查是否已存在相同类型的事件
            foreach (var entry in eventTrigger.triggers)
            {
                if (entry.eventID == EventTriggerType.Select)
                {
                    Debug.LogWarning($"GameObject '{gameObject.name}' 上已存在Select事件，将添加重复监听器");
                    break;
                }
            }
            
            var newEntry = new EventTrigger.Entry
            {
                eventID = EventTriggerType.Select
            };
            
            newEntry.callback.AddListener((data) => {
                method.Invoke(component, null);
            });

            eventTrigger.triggers.Add(newEntry);
        }

        private static void UIDeselectBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UIDeselectBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"取消选中绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), Type.EmptyTypes))
            {
                Debug.LogError($"取消选中方法签名错误：{method.Name} 必须是无参void方法");
                return;
            }
            
            var eventTrigger = gameObject.GetComponent<EventTrigger>() ?? gameObject.AddComponent<EventTrigger>();
            RecordUIComponent(component, eventTrigger); 
            
            // 检查是否已存在相同类型的事件
            foreach (var entry in eventTrigger.triggers)
            {
                if (entry.eventID == EventTriggerType.Deselect)
                {
                    Debug.LogWarning($"GameObject '{gameObject.name}' 上已存在Deselect事件，将添加重复监听器");
                    break;
                }
            }
            
            var newEntry = new EventTrigger.Entry
            {
                eventID = EventTriggerType.Deselect
            };
            
            newEntry.callback.AddListener((data) => {
                method.Invoke(component, null);
            });

            eventTrigger.triggers.Add(newEntry);
        }

        private static void UISubmitBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UISubmitBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"Submit绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), Type.EmptyTypes))
            {
                Debug.LogError($"Submit方法签名错误：{method.Name} 必须是无参void方法");
                return;
            }
            
            var eventTrigger = gameObject.GetComponent<EventTrigger>() ?? gameObject.AddComponent<EventTrigger>();
            RecordUIComponent(component, eventTrigger); 
            
            // 检查是否已存在相同类型的事件
            foreach (var entry in eventTrigger.triggers)
            {
                if (entry.eventID == EventTriggerType.Submit)
                {
                    Debug.LogWarning($"GameObject '{gameObject.name}' 上已存在Submit事件，将添加重复监听器");
                    break;
                }
            }
            
            var newEntry = new EventTrigger.Entry
            {
                eventID = EventTriggerType.Submit
            };
            
            newEntry.callback.AddListener((data) => {
                method.Invoke(component, null);
            });

            eventTrigger.triggers.Add(newEntry);
        }

        private static void UICancelBind(Component component, MethodInfo method)
        {
            var attr = GetCustomAttributeWithCache<UICancelBindAttribute>(method);
            if (attr == null) return;
            
            var gameObject = FindTransformWithPathCache(component.transform, attr.Path)?.gameObject;
            if (gameObject == null)
            {
                Debug.LogError($"Cancel绑定失败：路径 {attr.Path} 未找到GameObject");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), Type.EmptyTypes))
            {
                Debug.LogError($"Cancel方法签名错误：{method.Name} 必须是无参void方法");
                return;
            }

            var eventTrigger = gameObject.GetComponent<EventTrigger>() ?? gameObject.AddComponent<EventTrigger>();
            RecordUIComponent(component, eventTrigger); 
            
            // 检查是否已存在相同类型的事件
            foreach (var entry in eventTrigger.triggers)
            {
                if (entry.eventID == EventTriggerType.Cancel)
                {
                    Debug.LogWarning($"GameObject '{gameObject.name}' 上已存在Cancel事件，将添加重复监听器");
                    break;
                }
            }
            
            var newEntry = new EventTrigger.Entry
            {
                eventID = EventTriggerType.Cancel
            };
            
            newEntry.callback.AddListener((data) => {
                method.Invoke(component, null);
            });

            eventTrigger.triggers.Add(newEntry);
        }
    }
}